package com.semp.gu.ui.elements;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.semp.gu.blog.BlogServiceManager;
import com.semp.gu.codec.CodecManager;
import com.semp.gu.connector.ConnectorManager;
import com.semp.gu.domain.local.LocalAlbumElement;
import com.semp.gu.ui.session.Session;
import com.semp.gu.ui.util.FramePostioner;

public class OperationProgressFrame extends JFrame implements ActionListener, PropertyChangeListener {

	/**
	 * 
	 */
	private static final long	serialVersionUID	= -4698024137475370740L;
	// UI elements
	private JProgressBar		progressBar;
	private JLabel				operationLabel;
	private JLabel				percentLabel;
	private JButton				validateButton;
	// Services, injection needed
	private CodecManager		codecManager;
	private ConnectorManager	connectorManager;
	private BlogServiceManager	blogServiceManager;
	private Session				session;

	// Logger
	private final static Logger	logger				= LoggerFactory.getLogger(OperationProgressFrame.class);

	public OperationProgressFrame() {
		super();
		initGUI();
		initListeners();
		FramePostioner.center(this);
	}

	private void initGUI() {
		this.setSize(407, 139);
		getContentPane().setLayout(null);

		validateButton = new JButton();
		getContentPane().add(validateButton);
		validateButton.setText("OK");
		validateButton.setBounds(324, 79, 51, 21);
		validateButton.setEnabled(false);

		progressBar = new JProgressBar();
		getContentPane().add(progressBar);
		progressBar.setBounds(12, 12, 312, 20);
		// progressBar.setStringPainted(true);

		operationLabel = new JLabel();
		getContentPane().add(operationLabel);
		operationLabel.setBounds(12, 44, 312, 14);

		percentLabel = new JLabel();
		getContentPane().add(percentLabel);
		percentLabel.setText("0 %");
		percentLabel.setBounds(336, 18, 35, 14);

		// Hidden by default
		this.setVisible(false);
	}

	private void initListeners() {
		validateButton.addActionListener(this);
	}

	/*
	 * Start the main job baby !
	 */
	public void startOperations() {
		this.setVisible(true);
		Task processTask = new Task();
		processTask.addPropertyChangeListener(this);
		processTask.execute();
	}

	private class Task extends SwingWorker<Void, Void> {

		@Override
		protected Void doInBackground() throws Exception {
			List<LocalAlbumElement> elements = getSession().getLocalAlbum().getElements();
			int nbOperations = 2 * elements.size();
			int index = 1;

			for (LocalAlbumElement localAlbumElement : elements) {
				try {
					/*
					 * Operation 1: convert
					 */
					operationLabel.setText("Converting " + localAlbumElement.getName());
					codecManager.processElement(localAlbumElement);
				} catch (Exception e) {
					logger.error("", e);
				}
				setProgress(index * 100 / nbOperations);
				index++;
			}

			/*
			 * Operation 2: Upload
			 */
			for (LocalAlbumElement localAlbumElement : elements) {
				try {
					operationLabel.setText("Uploading files for " + localAlbumElement.getName());
					connectorManager.getSelectedConnector().uploadFile(localAlbumElement, getSession().getSelectedRemoteAlbum());
				} catch (Exception e) {
					logger.error("", e);
				}
				setProgress(index * 100 / nbOperations);
				index++;
			}

			/*
			 * Operation 3: Blog update
			 */
			operationLabel.setText("Updating blog");
			switch (session.getBlogAction()) {
			case ALBUMUPDATED:
				blogServiceManager.getSelectedBlogService().postAlbumUpdated(getSession().getLocalAlbum(), getSession().getSelectedRemoteAlbum());
				break;
			case NEWALBUM:
				blogServiceManager.getSelectedBlogService().postAlbumCreated(getSession().getLocalAlbum(), getSession().getSelectedRemoteAlbum());
				break;

			}
			

			operationLabel.setText("Operation completed !");
			validateButton.setEnabled(true);
			return null;
		}
	}

	public void propertyChange(PropertyChangeEvent evt) {
		if ("progress" == evt.getPropertyName()) {
			int progress = (Integer) evt.getNewValue();
			progressBar.setValue(progress);
			percentLabel.setText(progress + " %");
		}
	}

	public void actionPerformed(ActionEvent event) {
		if (event.getSource() == validateButton) {
			this.setVisible(false);
			validateButton.setEnabled(false);
		}
	}

	// Getters & Setters
	public CodecManager getCodecManager() {
		return codecManager;
	}

	public void setCodecManager(CodecManager codecManager) {
		this.codecManager = codecManager;
	}

	public Session getSession() {
		return session;
	}

	public void setSession(Session session) {
		this.session = session;
	}

	public ConnectorManager getConnectorManager() {
		return connectorManager;
	}

	public void setConnectorManager(ConnectorManager connectorManager) {
		this.connectorManager = connectorManager;
	}

	public BlogServiceManager getBlogServiceManager() {
		return blogServiceManager;
	}

	public void setBlogServiceManager(BlogServiceManager blogServiceManager) {
		this.blogServiceManager = blogServiceManager;
	}

}
